package com.solution.action;

import java.io.IOException;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;

import javax.naming.NamingException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.log4j.Logger;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;

import com.solution.constant.LoginConstants;
import com.solution.constant.SystemVariableConstants;
import com.solution.delegate.SystemVariableServiceDelegate;
import com.solution.delegate.UserInfoServiceDelegate;
import com.solution.delegate.UserRolePermissionServiceDelgate;
import com.solution.exception.DelegateException;
import com.solution.exception.ServiceBeanException;
import com.solution.model.SystemVariable;
import com.solution.model.UserInfo;
import com.solution.model.UserPermissionType;
import com.solution.model.UserRole;
import com.solution.service.UserRolePermissionService;


public class LoginFrontAction extends Action {

	Logger logger = Logger.getLogger(LoginFrontAction.class.getName());

	public ActionForward execute(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws IOException, ServletException {
		UserInfo userInfo = null;
		try {
			HttpSession session = request.getSession();
			if("/unauthenticatedRequest".equals(mapping.getPath())){
				return mapping.findForward("success");
			}
			 
			userInfo = getUserInfo(request);

			if(userInfo != null && userInfo.getStatus()!=null && (userInfo.getStatus()== LoginConstants.USER_DEACTIVE)){
				return mapping.findForward(LoginConstants.DEACTIVE_ACTION);
			}
			else if(userInfo.getStatus()!=null && userInfo.getStatus() == LoginConstants.USER_BLOCKED){
				return mapping.findForward(LoginConstants.BLOCKED_ACTION);
			}
			else if(userInfo.getStatus()!=null && userInfo.getStatus() == LoginConstants.USER_LOGIN_EXPIRED){
				return mapping.findForward(LoginConstants.EXPIRED_ACTION);
			}
			boolean isExaminee = checkForExaminee(userInfo);
			boolean isFirstLogin = checkFirstTimeLogin(userInfo);
			if(isFirstLogin && !isExaminee){
				 session.setAttribute(LoginConstants.SESSION_USER_PERMISSION_INFO, null);
				 return mapping.findForward(LoginConstants.CHANGE_PASSWORD_USER_ACTION);
			}
			updateUserSession(request,userInfo);
			 
			if(isExaminee){
				boolean isValidpasswordAge = checkPasswordAge(userInfo);
				if(!isValidpasswordAge){
					updateExemineeStatus(userInfo);
					return mapping.findForward(LoginConstants.EXPIRED_ACTION);
				}
				return mapping.findForward("success.examinee");
			}
			return mapping.findForward("success");
		} catch (Exception e) {
			logger.error("Error while updating user session(Exception)",e);
			return mapping.findForward(LoginConstants.FORWARD_ACTION_ERROR);
		}		
		
	}
	private void updateExemineeStatus(UserInfo userInfo){
		try{
			UserInfoServiceDelegate userInfoService = new UserInfoServiceDelegate();
			userInfo.setStatus(LoginConstants.USER_LOGIN_EXPIRED);
			userInfoService.update(userInfo);
			
		}catch(Exception e){			
		}
		
	}

	private boolean checkForExaminee(UserInfo userInfo){
		try{
			UserInfoServiceDelegate userInfoService = new UserInfoServiceDelegate();
			List<UserRole> userRoleList = userInfoService.getUserRoleList(userInfo.getId());
			if (userRoleList.get(0).getId().getUserRoleTypeId()== LoginConstants.USER_EXAMINEE){
				return true;
			}
		}catch(Exception e){			
		}
		return false;
	}
	private void updateUserSession(HttpServletRequest request,UserInfo userInfo)
			throws  NamingException,Exception {

		HttpSession session = request.getSession();
		String userName = (String) session.getAttribute(LoginConstants.SESSION_USERNAME);
		try{
			UserInfoServiceDelegate userInfoService = new UserInfoServiceDelegate();			
			UserRolePermissionService userRolePermissionService = new UserRolePermissionServiceDelgate();
			byte val=3;

			userInfo.setiPAddress(request.getRemoteAddr());
			userInfo.setSessionId(request.getSession().getId());
			userInfo.setRetryPasswordCount(val);
			userInfo.setLastLoggedOn(new Date());
			userInfoService.update(userInfo);

			UserInfo userInfoNew = userInfoService.getUserDetail(userName);
			List<UserPermissionType> permissionList = userRolePermissionService.getPermissionListByUserId(userInfoNew.getId());
			Iterator<UserPermissionType> itr = permissionList.iterator();
			HashMap hashMap = new HashMap();
			UserPermissionType permission;
			while(itr.hasNext())
			{
				permission = itr.next();
				hashMap.put(permission.getName(), permission.getName());
			}

			session.setAttribute(LoginConstants.SESSION_USER_INFO, userInfoNew);

			session.setAttribute(LoginConstants.SESSION_USER_PERMISSION_INFO, hashMap);


		} catch (Exception e) {
			throw e;
		}
	}
	private boolean checkFirstTimeLogin(UserInfo userInfo){

		if(userInfo.getLastLoggedOn()==null || "".equals(userInfo.getLastLoggedOn())){
			return true;
		}else{
			return false;
		}
	}


	private UserInfo getUserInfo(HttpServletRequest request) throws  NamingException,Exception {
		HttpSession session = request.getSession();
		UserInfo userInfo = (UserInfo) session.getAttribute(LoginConstants.SESSION_USER_INFO);
		String userName = (String) session.getAttribute(LoginConstants.SESSION_USERNAME);
		if (userName == null) {
			userName = request.getRemoteUser();
			session.setAttribute(LoginConstants.SESSION_USERNAME, userName);
			session.setAttribute(LoginConstants.SESSION_CONTEXT_PATH, request
					.getContextPath());
		}
		if (userName != null && userInfo == null) {
			try {
				UserInfoServiceDelegate userInfoService= new UserInfoServiceDelegate();
				userInfo = userInfoService.getUserDetail(userName);
				//userVO = service.viewUserInfo(userName);
			} catch (Exception e) {
				throw e;
			}
		}
		session.setAttribute(LoginConstants.SESSION_USER_INFO, userInfo);
		return userInfo;
	}

	private boolean checkPasswordAge(UserInfo userInfo) throws IOException, ServletException, ServiceBeanException, DelegateException {
		SystemVariableServiceDelegate systemVariableService = new SystemVariableServiceDelegate();
		SystemVariable systemVariable = systemVariableService.getValue(SystemVariableConstants.EXAMINEE_EXPIRY_DAYS, userInfo.getClientType().getId());
		long val=new Long(systemVariable.getVariableValue().trim());
		Calendar calPrevious = Calendar.getInstance();
		Calendar calToday = Calendar.getInstance();
		//String value = merchantParameter.getCurrentValue();
		//val=Long.parseLong(value);
		calPrevious.setTime(userInfo.getCreatedOn());
		calToday.setTime(new Date());
		long diff = (calToday.getTimeInMillis() - calPrevious.getTimeInMillis())/(1000 * 60 * 60 * 24);
		if(diff > val){
			return false;
		}else{
			return true;
		}
	}


}
